`timescale 1ns / 1ps

module dmem_ctrl(
    input clk,
    input rst,
    input clk_mem,

    input [31:0] mem_req_addr,
    input [31:0] mem_req_data,
    input mem_req_wen,
    input mem_req_valid,
    
    output reg mem_resp_valid,
    output [31:0] mem_resp_data
);

    reg mem_wen; 

    wire [31:0] mem_data_out;
    reg [31:0] mem_word_out;

    reg [31:0] mem_data_in;
    reg [31:0] mem_addr;

    reg [2:0] counter;

    assign mem_resp_data = mem_word_out;
 

    always @(posedge clk or posedge rst) begin
        if (rst) begin  
            mem_resp_valid <= 1'b0;
            mem_wen <= 1'b0;
            counter <= 3'b0;
            mem_word_out <= 32'b0;
				mem_addr <= 1'b0;
        end 
        else begin
            case (counter)
                3'b000: begin
                    if (mem_req_valid) counter <= counter + 1'b1;
                    mem_resp_valid <= 1'b0;
                    mem_wen <= 1'b0;
                end

                3'b001: begin
                    mem_wen <= mem_req_wen;
                    mem_addr <= mem_req_addr;
                    mem_data_in <= mem_req_data;
                    counter <= counter + 1'b1;
                end

                3'b010: begin
                    mem_addr <= 1'b0;
                    mem_wen <= 1'b0;
                    counter <= counter + 1'b1;                    
                end

                3'b011: begin
                    mem_word_out <= mem_data_out;
                    mem_resp_valid <= 1'b1;
                    counter <= counter + 1'b1; 
                end 

                3'b100: begin
                    mem_resp_valid <= 1'b0;
                    if (~mem_req_valid) counter <= 3'b0;
                end
            endcase


        end

    end 



    dmemory mem_data (
        
    /* port a for data write */
        .clka(clk), // input clka
        .rsta(rst), // input rsta
        .wea(mem_wen), // input [0 : 0] wea
        .addra(mem_addr[10:2]), // input [8 : 0] addra
        .dina(mem_data_in), // input [31 : 0] dina
        .douta(), // output [7 : 0] douta

    /* port b for data read */
        .clkb(clk), // input clkb
        .rstb(rst), // input rstb
        .web(1'b0), // input [0 : 0] web
        .addrb(mem_addr[10:2]), // input [8 : 0] addrb
        .dinb(), // input [7 : 0] dinb
        .doutb(mem_data_out) // output [31 : 0] doutb

    );

endmodule